<template>
    <div class="container">
        <!-- <h1>这里是登录路由</h1> -->
        <el-row>
            <!-- 注：“element”组件库的“栅格系统”把页面在宽度上分为24列。“span=12”表示“该属性的所在区域占据其中的12列”（也就是占据页面宽度的一半）。“xs”表示“页面在带有超小屏幕的设备（如手机）上显示时，该属性的所在区域应当占据的列数”（关于对“超小屏幕”的界定标准，老师的说法是“在显示分辨率上，屏幕宽度小于768像素”，但“文心快码”的说法是“屏幕尺寸的界定是相对的，并且可能因框架版本或具体实现而异（也就是说不一定宽度小于768像素就算是小屏幕）”）。↓ -->
            <!-- <el-col :span="12" :xs="0">左侧的图片区域</el-col> -->
            <el-col :span="12" :xs="0"></el-col>
            <el-col :span="12" :xs="24">
                <el-form class="loginForm" :model="formData" :rules="rules" ref="loginForm">
                    <h1>Hello</h1>
                    <h2>欢迎来到硅谷甄选</h2>
                    <el-form-item prop="username">
                        <!-- 注：属性“prexix-icon”被用于给输入框添加“前缀图标”，且由于图标“User”和“Lock”是组件，所以在此处需要使用“v-bind”的简写（冒号）把属性“prefix-icon”的值绑定为它们↓ -->
                        <el-input :prefix-icon="User" v-model="formData.username"></el-input>
                    </el-form-item>
                    <el-form-item prop="password">
                        <!-- 注：在此处，“show-password”是布尔属性，它被用于控制“是否显示密码”（实际上是把输入框的类型在“text”和“password”之间做切换）↓ -->
                        <el-input type="password" :prefix-icon="Lock" v-model="formData.password" show-password></el-input>
                    </el-form-item>
                    <el-form-item>
                        <el-button :loading="isLoading" class="loginButton" type="primary" size="default" @click="afunctionUsedToLogin">登录</el-button>
                    </el-form-item>
                </el-form>
            </el-col>
        </el-row>
    </div>
</template>
<script setup lang="ts">
import {User,Lock} from '@element-plus/icons-vue'
import {reactive,ref} from 'vue'
import {useRouter,useRoute} from 'vue-router'
import {ElNotification} from 'element-plus'
// 导入通过获取当前时间来判断当前处于哪个时间段的函数↓
import {aFunctionThatUsedToDetermineWhichTimePeriodItIsCurrentlyInByGettingTime} from '@/utils/time'
// 导入与“用户”相关的小仓库↓
import useUserStore from '@/store/modules/user'
let userStore = useUserStore();
// 获取表单组件实例↓
let loginForm = ref()
// 获取路由器对象↓
let router = useRouter();
// 获取路由对象↓
let route = useRoute()
// 收集表单数据↓
let formData = reactive({
    username: 'admin',
    password: '111111'
    // 注：把“mock接口”替换为“真实的登录接口”后，密码的默认值被改为“atguigu123”（但经实测，后来尚硅谷官方又把密码修改回“111111”）↑
    // password: 'atguigu123'
});
// 定义一个被用于控制登录按钮是否具有加载效果的变量↓
let isLoading = ref(false);
// 定义“自定义校验规则”需要用到的“校验器函数”（rule：校验规则；value：被输入到文本框中的内容；callback：在校验规则是否通过时都需要被调用的回调函数（在校验通过时放行，校验不通过时则调用构造函数Error创建一个内含提示信息的错误对象））↓
function validatorOfUsername(rule:any,value:string,callback:Function) {
    console.log("用户名的校验器被调用了")
    console.log(rule) // {required: true, field: 'username', fullField: 'username', type: 'string', validator: ƒ}
    console.log(value) // admin
    // 注：使用自定义校验规则的优势是“可以使用正则表达式”↓
    /* if(/^\d{5,10}/.test(value)){
        callback()
    }else{
        callback(new Error('用户名必须是数字，且长度为5到10位'))
    } */
    if(value.length >= 5 && value.length <= 10){
        callback()
    }else{
        callback(new Error('用户名的长度为5到10位'))
    }
}
function validatorOfPassword(rule:any,value:string,callback:Function) {
    console.log("密码的校验器被调用了")
    console.log(rule) // {required: true, field: 'password', fullField: 'password', type: 'string', validator: ƒ}
    console.log(value) // 111111（替换为真实接口后输出“atguigu123”）
    if(value.length >= 6 && value.length <= 15){
        callback()
    }else{
        callback(new Error('密码的长度为6到15位'))
    }
}
// 定义表单校验规则（它是一个配置对象）↓
const rules = {
    username:[
        // {required:true,message:'请输入用户名',trigger:'blur'},
        // {required:true,max:10,min:6,message:'用户名的长度最小为6个字符，最大为10个字符',trigger:'change'},
        {required:true,validator:validatorOfUsername,trigger:'blur'},
    ],
    password:[
        // {required:true,message:'请输入密码',trigger:'blur'},
        // {required:true,max:15,min:6,message:'密码的长度最小为6个字符，最大为15个字符',trigger:'change'},
        {required:true,validator:validatorOfPassword,trigger:'change'},
    ],
}
/**
 * 函数“afunctionUsedToLogin”用于登录↓
 */
 const afunctionUsedToLogin = async() => {
    console.log(loginForm.value); // Proxy(Object)（控制台中输出的代码表明可以获取到表单组件实例对象）
    // 通过下面的这一行代码来保证全部表单项校验通过后再发送请求↓
    let result = await loginForm.value.validate();
    console.log(result); // true 或 false（控制台中输出的代码表明可以获取到表单校验的结果）
    // 开始登录时，让登录按钮具备加载效果↓
    isLoading.value = true
    // 注：此处既可以使用“try...catch...”语句，也可以使用“.then()”语法，我选用前者↓
    try {
        // console.log(formData);
        // 注：在此处，由于“aFunctionForHandleUserLogin”是一个异步函数（即返回一个Promise对象），所以需要用“await”关键字等待其执行结果。由于关键字“await”将返回promise对象被解析成功后的解析结果，所以实际上此处是使用了关键字“await”来保证“登陆成功”↓
        let result = await userStore.aFunctionForHandleUserLogin(formData);
        console.log(result); // Promise {<pending>}
        // 注：在此处需要判断“路由路径”中是否带有“redirect”参数（它是一种“query”类型的参数）。如果有这个参数，则跳转到与这个参数对应的路径，否则则跳转到首页↓
        /* if(route.query.redirect) {
            router.push(route.query.redirect as string)
        } else{ // 没有这个参数，则跳转到首页↓
            // 注：此处使用了“编程式路由导航”中的“router.push()”方法来跳转到首页↓
            router.push('/');
        } */
       let redirect = route.query.redirect as string;
       router.push({path:redirect|| '/'})
        ElNotification({
            type: 'success',
            // message: '登陆成功',
            message: '欢迎回来',
            // 注：配置项中可以有标题，此处使用了“title”属性来为通知设置标题↓
           // title: '登录成功',
           title: `Hi，${aFunctionThatUsedToDetermineWhichTimePeriodItIsCurrentlyInByGettingTime()}`,
        })
        // 登录成功时，加载效果消失↓
        isLoading.value = false;
    } catch (error) {
        // 登录失败时，加载效果消失↓
        isLoading.value = false;
        ElNotification({
            type: 'error',
            // 注：此处使用了“as Error”语法，它是一种类型断言（Type Assertion），用于将一个表达式指定为一个更具体的类型。在这里，“(error as Error).message”会将错误对象断言为Error类型，然后访问其“message”属性。↓
            message: (error as Error).message,
        })
    }
    
}
/**
 * 函数“aFunctionThatUsedToDetermineWhichTimePeriodItIsCurrentlyInByGettingTime”被用于“获取当前时间，并根据其判断当前处于哪个时间段”↓
 */
/* function aFunctionThatUsedToDetermineWhichTimePeriodItIsCurrentlyInByGettingTime () {
    // 通过JS内置的构造函数“Date”获取当前时间中的小时数↓
    let hours = new Date().getHours();
    let message = ''
    console.log(hours);
    switch (true) {
        case hours < 6:
            message = '凌晨好';
            break;
        case hours < 9:
            message = '早上好';
            break;
        case hours < 12:
            message = '上午好';
            break;
        case hours < 14:
            message = '中午好';
            break;
        case hours < 17:
            message = '下午好';
            break;
        case hours < 19:
            message = '傍晚好';
            break;
        default:
            message = '晚上好';
            break;
    }
    console.log(message)
    return message;
} */
aFunctionThatUsedToDetermineWhichTimePeriodItIsCurrentlyInByGettingTime()
</script>
<style scoped lang="scss">
.container {
    /* 让容器宽度占满整个视口宽度（即100%的视口宽度）↓ */
    width: 100%;
    height: 100vh;
    background: url('@/assets/images/background.jpg') no-repeat;
    /* 让背景图覆盖整个容器，不留空白区域↓ */
    background-size: cover;
}

.loginForm {
    position: relative;
    width: 80%;
    top: 30vh;
    background: url('@/assets/images/login_form.png') no-repeat;
    background-size: cover;
    padding: 40px;

    h1 {
        color: white;
        font-size: 40px;
    }

    h2 {
        color: white;
        font-size: 20px;
        margin:20px 0px;
    }

    .loginButton {
        /* 与父元素等宽↓ */
        width: 100%;        
    }
}
</style>